#ifndef ASYNCRUNNER_H
#define ASYNCRUNNER_H

#include <QObject>
#include <QThread>
#include <Task/TaskApi.h>
#include <sys/time.h>
#include <AppConfig.h>
#include <QDir>
#include "Tools/Helper.h"
#include <QFileInfo>
#include <QIODevice>
#include <QFile>
#include <QTextStream>
#include <Tools/Helper.h>

/*
    异步的图像处理类，代理完成CPF系统api的全部访问操作
    完成后保存需要展示的json数据到runtime-cache中
    完成/失败后触发相关事件,接受信号的相关函数完成数据库/UI相关的数据更新

    由于系统性能受限，所以还需要一层外部封装，大致逻辑如下:
        1. LeftArea周期触发获取下一个病例的api cpp代码
        2. 在cpp函数中，首先判断AsyncRunner这个对象是否执行完成，没完成直接return false
        3. 如果AsyncRunner触发了完成回调，设置了外层封装的状态为完成(这里大概还包含数据库的写入等)
           则访问api获取**下一个对象**, return true
        4. 填写相关参数，开始下一次运算
        5. 由于创建了一个新的循环，说明图像处理完成了，所以ui相关要触发ui更新相关代码

    关于下一个对象:
        - 受限于算法执行效率，一个对象大约30s，远端虽然能支持多文件执行，但无法追踪每一个文件的执行
        - 如果崩溃的话，这一批的数据就相当于要重新执行，所以下面的代码虽然要求上传一个列表
        - 但是只能填写一个文件
*/

enum ResultEnum{
    SUCCESS = 0,
    RUNNING = 1,
    FAIL = 2
};

typedef struct RunnerResult{
    ResultEnum taskStatus;  // 此线程执行是否成功
    QString taskId;  // 创建的任务id
    QString options;  // 此任务执行的远程参数
    QString okRes;  // 通常为远程需要渲染的json str
    QString errMsg;  // 报错信息
}AsyncRunnerResult;


class AsyncRunner : public QThread
{
    Q_OBJECT

signals:
    void AsyncDone(const AsyncRunnerResult res);

public:
    explicit AsyncRunner(const QString patientName, const QString patientId,
                         const QVector<QString>& fileList, const QString runningOptions);

private:
    void loopMain();
    bool saveResultToFile(const QString res);
    SyncTaskApi::RemoteApiResult createTask();
    SyncTaskApi::RemoteApiResult uploadTask();
    SyncTaskApi::RemoteApiResult putTask();
    SyncTaskApi::ApiTaskProgress queryTask();
    SyncTaskApi::RemoteApiResult queryResult();

protected:
    void run() override;

private:
    const QString patientName;  // 病人名称
    const QString patientId;  // 病人拍摄id
    const QVector<QString> fileList;
    QString taskId;
    const QString runningOptions;
};

#endif // ASYNCRUNNER_H
